home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Information / CSMP Digest / volume 3 / csmp-digest-v3-064 < prev    next >
Text File  |  1995-12-31  |  53KB  |  1,477 lines

  1. Received-Date: Sat, 8 Oct 1994 14:49:48 +0100
  2. From: pottier@clipper.ens.fr (Francois Pottier)
  3. Subject: csmp-digest-v3-064
  4. To: csmp-digest@ens.fr
  5. Date: Sat, 8 Oct 1994 14:49:41 +0100 (MET)
  6. X-Mailer: ELM [version 2.4 PL23]
  7. Mime-Version: 1.0
  8. Content-Type: text/plain; charset=ISO-8859-1
  9. Content-Transfer-Encoding: 8bit
  10. Errors-To: listman@ens.fr
  11. Reply-To: pottier@clipper.ens.fr
  12. X-Sequence: 69
  13.  
  14. C.S.M.P. Digest             Sat, 08 Oct 94       Volume 3 : Issue 64
  15.  
  16. Today's Topics:
  17.  
  18.         Help!! argc, argv on Macintosh
  19.         How to Check if drivers are open
  20.         Is it possible to notify another mac?
  21.         Memory moving and Inits
  22.         Self-disposing notification crashes
  23.         [CWWWW] PowerPlant Tour document available
  24.  
  25.  
  26.  
  27. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  28. (pottier@clipper.ens.fr).
  29.  
  30. The digest is a collection of article threads from the internet newsgroup
  31. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  32. regularly and want an archive of the discussions.  If you don't know what a
  33. newsgroup is, you probably don't have access to it.  Ask your systems
  34. administrator(s) for details.  If you don't have access to news, you may
  35. still be able to post messages to the group by using a mail server like
  36. anon.penet.fi (mail help@anon.penet.fi for more information).
  37.  
  38. Each issue of the digest contains one or more sets of articles (called
  39. threads), with each set corresponding to a 'discussion' of a particular
  40. subject.  The articles are not edited; all articles included in this digest
  41. are in their original posted form (as received by our news server at
  42. nef.ens.fr).  Article threads are not added to the digest until the last
  43. article added to the thread is at least two weeks old (this is to ensure that
  44. the thread is dead before adding it to the digest).  Article threads that
  45. consist of only one message are generally not included in the digest.
  46.  
  47. The digest is officially distributed by two means, by email and ftp.
  48.  
  49. If you want to receive the digest by mail, send email to listserv@ens.fr
  50. with no subject and one of the following commands as body:
  51.     help                        Sends you a summary of commands
  52.     subscribe csmp-digest Your Name    Adds you to the mailing list
  53.     signoff csmp-digest            Removes you from the list
  54. Once you have subscribed, you will automatically receive each new
  55. issue as it is created.
  56.  
  57. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  58. Questions related to the ftp site should be directed to
  59. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  60. digest are available there.
  61.  
  62. Also, the digests are available to WAIS users.  To search back issues
  63. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  64. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  65.  
  66.  
  67. -------------------------------------------------------
  68.  
  69. >From victor chong <victorc@sleepy.cc.utexas.edu>
  70. Subject: Help!! argc, argv on Macintosh
  71. Date: 22 Sep 1994 21:19:15 GMT
  72. Organization: UT Austin
  73.  
  74. Hi,
  75.     I was wondering if someone could enlighten me concerning
  76. the usage of argv and argc when programming on the Macintosh.
  77. I'm using Symantec C++.
  78.     Does the Mac allows this kind of communication with the
  79. OS or is there another method.
  80.     Any kind of help will be much welcome.
  81.     Thank you very much.
  82.     
  83.     
  84.     
  85.     
  86. victor
  87.  
  88. victorc@sleepy.cc.utexas.edu
  89.  
  90. +++++++++++++++++++++++++++
  91.  
  92. >From Eric.M.Kidd@dartmouth.edu (Eric M. Kidd)
  93. Date: 23 Sep 1994 00:11:36 GMT
  94. Organization: Dartmouth College, Hanover, NH
  95.  
  96. argc and argv do not work at all on any normal mac setup. Sorry.
  97.  
  98. The following program fragment gives an idea of how to get the
  99. old-fashioned app params (files to open or print). If you want to do
  100. anything more complicated, you'll need to use Apple Events.
  101.  
  102. /* openingFiles( )
  103. **
  104. ** Determine if we have parameters. The old-style app parameters are
  105. used for
  106. ** the sake of SPEED. Apple Events are too slow, and I only have
  107. partial docs.
  108. ** Help in acquiring copies of Inside Macintosh always welcome...
  109. */
  110.  
  111. Boolean openingFiles( )
  112. {
  113.     short message;
  114.     short count;
  115.     
  116.     CountAppFiles( &message, &count );
  117.     
  118.     return ( message == 0 && count > 0 );
  119. }
  120.  
  121. /* openFiles( )
  122. **
  123. ** Go through files one by one, processing them along the way.
  124. */
  125.  
  126. void openFiles( )
  127. {
  128.     FSSpec cur;
  129.     AppFile aFile;
  130.     short count;
  131.     short i;
  132.     short mess;
  133.     
  134.     /* I'm not bothering to check for print messages--my app shouldn't get
  135. any */
  136.     CountAppFiles( &mess, &count );
  137.     
  138.     for ( i = 1; i <= count; i++ )
  139.     {
  140.         /* get file and convert from working dir to FSSpec */
  141.         GetAppFiles( i, &aFile );
  142.         FSMakeFSSpec( aFile.vRefNum, 0, aFile.fName, &cur );
  143.         
  144.         processFile( &cur );
  145.     }
  146. }
  147.  
  148. main( )
  149. {
  150.     initMacintosh( );
  151.     initApplication( );
  152.     
  153.     if ( openingFiles( ) )
  154.         openFiles( );
  155.     else
  156.         runApplication( );
  157. }
  158.  
  159. +++++++++++++++++++++++++++
  160.  
  161. >From ruhl@du.edu (ROBERT A. UHL )
  162. Date: Fri, 23 Sep 1994 15:34:11 GMT
  163. Organization: University of Denver
  164.  
  165.   Does anybody have the format of the Handle returned by
  166. GetAppParms()? I don't have IM and have to figure out what the
  167. functions do from the headers. Any help would be appreciated.
  168. -- 
  169. - ------------------------------------
  170. | Bob Uhl | Spectre                  |
  171. | U of D  | Baron Robert von Raetzin |
  172.  
  173. +++++++++++++++++++++++++++
  174.  
  175. >From Carl R. Osterwald <carl_osterwald@nrel.gov>
  176. Date: Fri, 23 Sep 1994 20:48:32 GMT
  177. Organization: National Renewable Energy Laboratory
  178.  
  179. In article <35ssck$m3a@geraldo.cc.utexas.edu> victor chong,
  180. victorc@sleepy.cc.utexas.edu writes:
  181. >    I was wondering if someone could enlighten me concerning
  182. >the usage of argv and argc when programming on the Macintosh.
  183. >I'm using Symantec C++.
  184. >    Does the Mac allows this kind of communication with the
  185. >OS or is there another method.
  186.  
  187. Just use the Symantec console package.  You will need to add one key
  188. element, a ccommand() call, before you access argv/argc.  This puts up a
  189. dialog box that allows you to type in the command line parameters. 
  190. ccommand() was documented in the Think C 5 manuals, in 6 and 7 it is
  191. online inside the free version of Think Reference (I have not verified
  192. this personally).
  193.  
  194. For disk I/O be sure to check the c.s.m.p PD programming FAQ compiled by
  195. Jon Watte.
  196.  
  197. +++++++++++++++++++++++++++
  198.  
  199. >From rrk@rahul.net (Bob R. Kenyon)
  200. Date: Sat, 24 Sep 1994 05:54:04 GMT
  201. Organization: La Casita de Las Pulgas, San Jose, CA
  202.  
  203. In article <35ssck$m3a@geraldo.cc.utexas.edu>, victor chong
  204. <victorc@sleepy.cc.utexas.edu> wrote:
  205.  
  206. > Hi,
  207. >         I was wondering if someone could enlighten me concerning
  208. > the usage of argv and argc when programming on the Macintosh.
  209. > I'm using Symantec C++.
  210. >         Does the Mac allows this kind of communication with the
  211. > OS or is there another method.
  212. >         Any kind of help will be much welcome.
  213. >         Thank you very much.
  214.  
  215. Yeah, if you look in Think Reference, they talk about a function called
  216. ccommand. When your program starts, it throws up a window that allows you
  217. to redirect input and output, and enter command line arguments. It's
  218. pretty funny actually, but not really "Mac" in behavior.
  219.  
  220. Their code example looks like this:
  221.  
  222.  
  223. /* CODE EXAMPLE #1 */
  224. #include <stdio.h>
  225. #include <console.h>
  226.  
  227. main(int argc, char **argv)
  228. {
  229.    int i;
  230.  
  231.    argc = ccommand(&argv);  // this is the command that throws up the window
  232.  
  233.    for (i=0; i<argc; i++)
  234.       printf ("%s ", argv[i]);
  235.  
  236.    printf ("\n");
  237. }
  238.  
  239. I use this technique all the time for my programming classes, because they
  240. haven't covered any kind of windowing stuff. 
  241.  
  242. Hope this helps,
  243. Bob
  244.  
  245. -- 
  246. Bob Kenyon                           | "Pilots take no special joy
  247. Beautiful Downtown San Jose, CA      |  in walking. Pilots like
  248. rrk@rahul.net                        |  flying." -- Neil Armstrong
  249.  
  250. ---------------------------
  251.  
  252. >From ferrari@netaxs.com (Darrell Turner)
  253. Subject: How to Check if drivers are open
  254. Date: Thu, 22 Sep 1994 13:26:38 -0500
  255. Organization: Haha, None here
  256.  
  257. I'm trying to figure out how to check if a driver is open by only
  258. specifying the driver name.  I want it to work for .IPP .AOut, and others
  259. such as ram serail drivers for Hurdlers, etc.
  260.  
  261. My problem is that I can't figure out if it's open without first knowing
  262. the driver unit number.  I was going to walk the UnitTable checking for the
  263. Driver Name  in the DCtlEntry, but I soon discovered that the name is in
  264. there.  This is my current code, and it doesn't work, how can I get this
  265. working?  (The GetNamedResource returns nil, even on stuff I know is in the
  266. System file like .AOut.
  267.  
  268.     function GetNamedDCtlEntry (driverName: str255): DCtlHandle;
  269.         type
  270.             Ptr2Word = ^integer;
  271.             Ptr2Byte = ^byte;
  272.         const
  273.             UnitNtryCnt = $1D2; {[GLOBAL VAR]  count of entries in unit table
  274. [word]}
  275.             RomMapInsert = $B9E;{[GLOBAL VAR] (byte) determines if we should link in
  276. map}
  277.  
  278.         var
  279.             rID: integer;
  280.             rType: ResType;
  281.             hand: handle;
  282.     begin
  283.         SetResLoad(false);
  284.         Ptr2Byte(RomMapInsert)^ := 1;
  285.         hand := GetNamedResource('DRVR', driverName);
  286.         SetResLoad(true);
  287.         GetResInfo(hand, rID, rType, driverName);
  288.         if (rID >= 0) and (rID <= Ptr2Word(UnitNtryCnt)^) then
  289.             GetNamedDCtlEntry := GetDCtlEntry(rID)
  290.         else
  291.             GetNamedDCtlEntry := nil;
  292.     end;
  293.  
  294. begin
  295.     dctl := GetNamedDCtlEntry('.IPP');
  296.     if dCtl = nil then
  297.         Quit(noErr);
  298.     Init;
  299.     repeat
  300.         HandleEvents;
  301.     until (BitTst(@dctl^^.dCtlFlags, 5) or done);
  302.  {...}
  303. end.
  304.  
  305. +++++++++++++++++++++++++++
  306.  
  307. >From resnick@uiuc.edu (Pete Resnick)
  308. Date: Fri, 23 Sep 1994 12:36:16 -0500
  309. Organization: University of Illinois at Urbana-Champaign
  310.  
  311. In article <ferrari-220994132639@slip-55.netaxs.com>, ferrari@netaxs.com (Darrell Turner) wrote:
  312.  
  313. > I'm trying to figure out how to check if a driver is open by only
  314. > specifying the driver name.  I want it to work for .IPP .AOut, and others
  315. > such as ram serail drivers for Hurdlers, etc.
  316. > My problem is that I can't figure out if it's open without first knowing
  317. > the driver unit number.  I was going to walk the UnitTable checking for the
  318. > Driver Name  in the DCtlEntry, but I soon discovered that the name is in
  319. > there.
  320.  
  321. Yes it is. It's in the driver itself, which is pointed to by the DCtl
  322. entry. Here's some code (in C; the conversion to Pascal is pretty easy):
  323.  
  324. /* Structure of the driver resource */
  325. typedef struct {
  326.     short drvrFlags;
  327.     short drvrDelay;
  328.     short drvrEMask;
  329.     short drvrMenu;
  330.     short drvrOpen;
  331.     short drvrPrime;
  332.     short drvrCtl;
  333.     short drvrStatus;
  334.     short drvrClose;
  335.     unsigned char drvrName[];
  336.     unsigned char drvrRoutines[];
  337. } DriverStruct, *DriverPtr, **DriverHandle;
  338.  
  339. #if define(__SYSEQU__)
  340. #define UTABLEBASE  (* (DCtlHandle **)UTableBase)
  341. #define UNITNTRYCNT (* (short *)UnitNtryCnt)
  342. #elif defined(__LOWMEM__)
  343. #define UTABLEBASE  (DCtlHandle *)LMGetUTableBase()
  344. #define UNITNTRYCNT LMGetUnitNtryCnt()
  345. #else
  346. #define UTABLEBASE  UTableBase
  347. #define UNITNTRYCNT UnitNtryCnt
  348. #endif
  349.  
  350. #ifndef dOpened
  351. #   define dOpened      0x0020
  352. #endif /* dOpened */
  353. #ifndef dRAMBased
  354. #   define dRAMBased    0x0040
  355. #endif /* dRAMBased */
  356.  
  357. short GetDrvrRefNum(StringPtr drvrName)
  358. {
  359.   short unitNum;
  360.   DCtlPtr curDCtlPtr, *curDCtlHndl, **UTableEntry;
  361.   DriverPtr curDrvrPtr;
  362.     
  363.   /* Walk through the Unit Table */
  364.   UTableEntry = UTABLEBASE;
  365.   for(unitNum = 0; unitNum < UNITNTRYCNT; ++unitNum) {
  366.     if((curDCtlHndl = *UTableEntry++) != nil) {
  367.             
  368.       curDCtlPtr = *curDCtlHndl;
  369.             
  370.       /* Get the pointer to the driver */
  371.       curDrvrPtr = (DriverPtr)curDCtlPtr->dCtlDriver;
  372.  
  373.       /* If this is a RAM driver, it's a handle. ROM is a pointer */
  374.       if((curDCtlPtr->dCtlFlags & dRAMBased) && (curDrvrPtr != nil))
  375.         curDrvrPtr = *(DriverPtr *)curDrvrPtr;
  376.             
  377.       /* Does the driver name match? */
  378.       if(curDrvrPtr != nil)
  379.         if(EqualString(drvrName, curDrvrPtr->drvrName, false, true))
  380.           return(~unitNum);
  381.     }
  382.   }
  383.   return(0);
  384. }
  385.  
  386. Boolean IsDriverOpen(StringPtr drvrName)
  387. {
  388.   short unitNum;
  389.   DCtlPtr curDCtlPtr, *curDCtlHndl, **UTableEntry;
  390.   DriverPtr curDrvrPtr;
  391.     
  392.   /* Walk through the Unit Table */
  393.   UTableEntry = UTABLEBASE;
  394.   for(unitNum = 0; unitNum < UNITNTRYCNT; ++unitNum) {
  395.     if((curDCtlHndl = *UTableEntry++) != nil) {
  396.             
  397.       curDCtlPtr = *curDCtlHndl;
  398.             
  399.       /* Get the pointer to the driver */
  400.       curDrvrPtr = (DriverPtr)curDCtlPtr->dCtlDriver;
  401.  
  402.       /* If this is a RAM driver, it's a handle. ROM is a pointer */
  403.       if((curDCtlPtr->dCtlFlags & dRAMBased) && (curDrvrPtr != nil))
  404.         curDrvrPtr = *(DriverPtr *)curDrvrPtr;
  405.             
  406.       /* Does the driver name match? */
  407.       if(curDrvrPtr != nil)
  408.         if(EqualString(drvrName, curDrvrPtr->drvrName, false, true))
  409.           return((curDCtlPtr->dCtlFlags & dOpened) != 0);
  410.     }
  411.   }
  412.   return(false);
  413. }
  414.  
  415. Note: There is an omission in the Universal headers LowMem.h because it
  416. does not define LMGetUnitNtryCnt or LMSetUnitNtryCnt. For the 68000
  417. versions, add:
  418.  
  419. #define LMGetUnitNtryCnt() (* (short *) 0x01D2)
  420.  
  421. #define LMSetUnitNtryCnt(UnitNtryCntValue) ((* (short *) 0x01D2) = (UnitNtryCntValue))
  422.  
  423. I don't know what to do about the PowerPC versions.
  424.  
  425. pr
  426. -- 
  427. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  428. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  429. System manager - Cognitive Science Group, Beckman Institute, UIUC
  430. Internet: resnick@uiuc.edu
  431.  
  432. +++++++++++++++++++++++++++
  433.  
  434. >From csuley@netcom.com (Christopher S. Suley)
  435. Date: Sat, 24 Sep 1994 05:58:12 GMT
  436. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  437.  
  438.  
  439. Here's some code I use to find a driver in the unit table.
  440. It's lightly adapted from Pete Resnick's excellent Driver 2.2,
  441. available at sumex and umich and mirrors thereof.
  442. It's in C, but the translation to Pascal should be pretty easy.
  443.  
  444.  
  445. typedef struct
  446. {
  447.   short drvrFlags;
  448.   short drvrDelay;
  449.   short drvrEMask;
  450.   short drvrMenu;
  451.   short drvrOpen;
  452.   short drvrPrime;
  453.   short drvrCtl;
  454.   short drvrStatus;
  455.   short drvrClose;
  456.   unsigned char drvrName[1]; /* actually variable length p-string */
  457. }
  458. DriverStruct, *DriverPtr;
  459.  
  460. short
  461. FindDriver( void )
  462. {
  463.   Str255      drvrName;
  464.   DCtlHandle  hCurDCE;
  465.   DriverPtr   pCurDrvr;
  466.   short       sDrvrNum;
  467.  
  468.   GetIndString( drvrName, krMiscStrings, ksiDriverNameIndex );
  469.  
  470.   for ( sDrvrNum = LMGetUnitNtryCnt() ; sDrvrNum >= 0 ; --sDrvrNum )
  471.   {
  472.     hCurDCE = GetDCtlEntry( ~sDrvrNum );
  473.     if ( hCurDCE )
  474.     {
  475.       pCurDrvr = ( DriverPtr ) (**hCurDCE).dCtlDriver;
  476.  
  477.       if ( ((**hCurDCE).dCtlFlags & dRAMBased) && pCurDrvr )
  478.       {
  479.         pCurDrvr = *( DriverPtr * ) pCurDrvr;
  480.       }
  481.  
  482.       if ( pCurDrvr &&
  483.            EqualString( drvrName, pCurDrvr->drvrName, false, true ) )
  484.       {
  485.         return ~sDrvrNum;
  486.       }
  487.     }
  488.   }
  489.  
  490.   return 0;
  491. }
  492.  
  493.  
  494. -- 
  495. Want some? <slap, thud>                                       csuley@netcom.com
  496. Want some? <slap, thud>                             ChrisSuley@{eworld,aol}.com
  497.  
  498. ---------------------------
  499.  
  500. >From altitude@umich.edu (Alex Tang)
  501. Subject: Is it possible to notify another mac?
  502. Date: 23 Sep 1994 21:09:51 GMT
  503. Organization: University of Michigan
  504.  
  505. Hi folks.  
  506.  
  507. I was wondering if it was possible to pull up a dialog box or alert box on
  508. another mac via either AppleTalk or IP.  
  509.  
  510. Me 'n some friends want to write an app that will (in it's most simple
  511. incarnation) open up an alert box on another mac and give them a piece of
  512. information.  
  513.  
  514. In it's most complicated incarnation, we would really like to be able to
  515. have one mac contact the notification manager on another mac, and run a
  516. program on that mac.
  517.  
  518. This is all presuming we know the AppleTalk node or IP address of the
  519. sending and receiving mac.
  520.  
  521. Thanx
  522. ...alex...
  523.  
  524.  
  525. --
  526.     Alex Tang      |     UM-SNRE   |       UM-ITD/US Consultant II
  527. ALTITUDE@UMICH.EDU |     Student   |    UM-SNRE-NCEET: Systems Admin
  528.   PGP via finger.  | Systems Admin |http://www.snre.umich.edu/users/altitude
  529. This space for rent|Comp.Consut III| An eye for an eye leaves everyone blind.
  530.  
  531. +++++++++++++++++++++++++++
  532.  
  533. >From nick+@pitt.edu ( nick.c )
  534. Date: Fri, 23 Sep 94 20:42:20 GMT
  535. Organization: The Pitt, Chemistry
  536.  
  537. In Article <35vg70$7v6@lastactionhero.rs.itd.umich.edu>, altitude@umich.edu
  538. (Alex Tang) wrote:
  539.  
  540. >I was wondering if it was possible to pull up a dialog box or alert box on
  541. >another mac via either AppleTalk or IP.  
  542. >
  543. >Me 'n some friends want to write an app that will (in it's most simple
  544. >incarnation) open up an alert box on another mac and give them a piece of
  545. >information.  
  546. >
  547. >In it's most complicated incarnation, we would really like to be able to
  548. >have one mac contact the notification manager on another mac, and run a
  549. >program on that mac.
  550.  
  551.  
  552.     Possible and been done.  I remember seeing a notification like
  553.       program on Umich... forget the name... "Broadcast"?.  Dunno.
  554.       Anyway, as I recall you have to have program linking on on the 
  555.       receiving mac, and have to have loaded an extension on the
  556.       receiving mac that takes your message and forwards it to the
  557.       local notification manager.  You could also create an extension
  558.       that sends out apple events, so could launch a local program
  559.       when keyed remotely.  I'd check out NIM:networking for more
  560.       details, luck
  561.  
  562.                                         -- nick
  563.  
  564.  
  565.  
  566.                                     _/   _/  _/  _/_/_/   _/   _/  
  567.      Interet: nick@pitt.edu        _/_/ _/  _/  _/   _/  _/_/_/    
  568.       eWorld: nick                _/ _/_/  _/  _/       _/ _/      
  569.          CIS: 71232,766          _/   _/  _/   _/_/_/  _/   _/     
  570.  
  571.  
  572. +++++++++++++++++++++++++++
  573.  
  574. >From jonasw@lysator.liu.se (Jonas Wallden)
  575. Date: 24 Sep 1994 21:19:28 GMT
  576. Organization: (none)
  577.  
  578. altitude@umich.edu (Alex Tang) writes:
  579.  
  580. >Hi folks.  
  581. >
  582. >I was wondering if it was possible to pull up a dialog box or alert box on
  583. >another mac via either AppleTalk or IP.  
  584. >
  585. >Me 'n some friends want to write an app that will (in it's most simple
  586. >incarnation) open up an alert box on another mac and give them a piece of
  587. >information.  
  588. >
  589. >In it's most complicated incarnation, we would really like to be able to
  590. >have one mac contact the notification manager on another mac, and run a
  591. >program on that mac.
  592. >
  593. >This is all presuming we know the AppleTalk node or IP address of the
  594. >sending and receiving mac.
  595.  
  596. A nice little hack is 'Radiation + Trigger' which can be used to fake
  597. error messages on anoter Mac's screen. Very useful in lab rooms... :-)
  598. It is an INIT that receives messages through the PPC Toolbox and displays
  599. them as Notification Manager alerts.
  600.  
  601. BTW, the default message is 'The radiation shield on your Macintosh has
  602. failed. Please step back 5 feet.' which explains its name... Use with
  603. care on newbies!
  604.  
  605. --
  606. `.`.   Jonas Wallden                    `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  607. `.`.`.   Internet: jonasw@lysator.liu.se  `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  608. `.`.`.`.   AppleLink: sw1369                `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  609.  
  610. ---------------------------
  611.  
  612. >From jlawrie@malibu.sfu.ca (John William Lawrie)
  613. Subject: Memory moving and Inits
  614. Date: 16 Sep 94 17:13:25 GMT
  615. Organization: Simon Fraser University
  616.  
  617. Hi.  I want to have an extension that performs periodic taks.  I have
  618. a skeleton extension that does this already, but the problem is, I
  619. will want to call toolbox routines that will call the memory manager.
  620. Is there a way around this?
  621.  
  622. John@helix.net
  623.  
  624.  
  625. +++++++++++++++++++++++++++
  626.  
  627. >From onyxtech@aol.com (OnyxTech)
  628. Date: 17 Sep 1994 04:26:02 -0400
  629. Organization: America Online, Inc. (1-800-827-6364)
  630.  
  631. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  632. Lawrie) writes:
  633.  
  634. > Hi.  I want to have an extension that performs periodic
  635. > taks.  I have a skeleton extension that does this already,
  636. > but the problem is, I will want to call toolbox routines
  637. > that will call the memory manager. Is there a way around
  638. > this?
  639.  
  640. It's ok to move memory in a trap patch, but It all depends on what you're
  641. using to trigger your extension code?  If you're installing a time manager
  642. or VBL routine, forget trying to move memory during that code because they
  643. can/will be executed during interupt time and moving memory then is a
  644. strict no no.  If you are triggering your extension code off a trap patch,
  645. them make sure it is a trap patch that can move memory.  Then you're ok. 
  646. If you are triggering off a trap patch that isn't documented as moving
  647. memory, you'd better change your code because you'll eventually get in
  648. trouble. And since I'm not sure what you're patching, better make sure
  649. that what your trap patch calls does not lead to what you're patching. 
  650. Re-entrant city unless you handle it correctly.
  651.  
  652. dEVoN
  653.  
  654. +++++++++++++++++++++++++++
  655.  
  656. >From jcornish@netcom.com (Jud Cornish)
  657. Date: Sun, 18 Sep 1994 08:32:34 GMT
  658. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  659.  
  660. To perform periodic tasks that may move/purge memory:
  661.  
  662. A simple solution is to patch a trap (or several) that are known to
  663. move/purge memory and are commonly called.  I did some "OS Profiling" of
  664. my own to identify a set of traps that I could patch that would give
  665. frequent time to such a task.  The other objective was to get time when
  666. apps, the OS or the Toolbox is in a tight loop such as while tracking a
  667. close box.  If you patch any one trap, there will be times when you can go
  668. for quite some time without an opportunity to snag some time.  I shouldn't
  669. go into the details, but with some common sense (and a little time with
  670. macsbug) one can pick a pretty good set of traps.  All this is only
  671. necessary if you have a really critical time based task.  Not critical in
  672. accuracy, but in avoiding long pauses.  All this is necessary because of
  673. the way "multi-tasking" is done on the mac.  Processes are only granted
  674. time when others share it. 
  675.  
  676. Another option would be to install a driver which requested periodic time. 
  677. This is actually harder than just patching _SystemTask, which I believe
  678. would function identically. 
  679.  
  680. Yet another option is to pre-allocate some memory with your INIT, then eat
  681. it up as you need it.  In a sense, depending on the complexity of your
  682. memory use, you can just start filling up a simple buffer with data, or
  683. you could make your own sub memory manager!!! 
  684.  
  685. A hybrid solution is to perform periodic tasks via the time manager, with
  686. accuracy and nearly guaranteed time, then when you fill up your buffer (or
  687. get sufficiently close to it), you set a flag which a _SystemTask patch
  688. can use to know when to grow the buffer.  You would need to temporarily
  689. suspend your use of the buffer while the patch is growing (and probably
  690. moving) it.  This can be done with another flag manipulated just before
  691. and after the SetHandleSize. The periodic task would always make sure this
  692. flag was clear before dereferencing the handle and using the buffer. 
  693.  
  694. I have little idea what your actual needs are but I hope that this
  695. discussion is helpful.  Hopefully, a simple patch will suffice.  As far as
  696. I have seen (68k sys 7.5), the OS still calls _SystemTask periodically. 
  697. If this is indeed the case, it is a good target as other processes will
  698. expect to share time when this happens (usually from a _waitNextEvent
  699. call). 
  700.  
  701. Any comments on my comments would be appreciated.
  702.  
  703. Erik J. Rogers
  704.  
  705. +++++++++++++++++++++++++++
  706.  
  707. >From resnick@uiuc.edu (Pete Resnick)
  708. Date: Sun, 18 Sep 1994 13:00:37 -0500
  709. Organization: University of Illinois at Urbana-Champaign
  710.  
  711. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  712. Lawrie) wrote:
  713.  
  714. > Hi.  I want to have an extension that performs periodic taks.  I have
  715. > a skeleton extension that does this already, but the problem is, I
  716. > will want to call toolbox routines that will call the memory manager.
  717. > Is there a way around this?
  718.  
  719. My personal favorite is to use a Time Manager task to do the periodic
  720. part, and have the completion proc for the Time Manager routine post a
  721. Notification Manager request that has all the fields except nmResp
  722. cleared. In the notification response, you can do whatever you want to do
  723. since it is Memory Manager safe.
  724.  
  725. pr
  726. -- 
  727. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  728. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  729. System manager - Cognitive Science Group, Beckman Institute, UIUC
  730. Internet: resnick@uiuc.edu
  731.  
  732. +++++++++++++++++++++++++++
  733.  
  734. >From Jaeger@fquest.com (Brian Stern)
  735. Date: 19 Sep 1994 05:03:25 GMT
  736. Organization: The University of Texas at Austin, Austin, Texas
  737.  
  738. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  739. Lawrie) wrote:
  740.  
  741. < Hi.  I want to have an extension that performs periodic taks.  I have
  742. < a skeleton extension that does this already, but the problem is, I
  743. < will want to call toolbox routines that will call the memory manager.
  744. < Is there a way around this?
  745. < John@helix.net
  746.  
  747. A jGNEFilter is a simple way to get periodic time and you can move memory
  748. if you need to.  The only problem is that you aren't guaranteed that it
  749. will be called frequently.
  750.  
  751. -- 
  752. Brian  Stern  :-{)}
  753. Jaeger@fquest.com
  754.  
  755. +++++++++++++++++++++++++++
  756.  
  757. >From blob@apple.com (Brian Bechtel)
  758. Date: 24 Sep 1994 14:39:56 -0700
  759. Organization: Apple Computer, Inc., Cupertino, California
  760.  
  761. Jaeger@fquest.com (Brian Stern) writes:
  762.  
  763. >In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  764. >Lawrie) wrote:
  765.  
  766. >< Hi.  I want to have an extension that performs periodic taks.  I have
  767. >< a skeleton extension that does this already, but the problem is, I
  768. >< will want to call toolbox routines that will call the memory manager.
  769. >< Is there a way around this?
  770.  
  771. >A jGNEFilter is a simple way to get periodic time and you can move memory
  772. >if you need to.  The only problem is that you aren't guaranteed that it
  773. >will be called frequently.
  774.  
  775. Even better is a faceless background application.  You can call any
  776. toolbox routine that doesn't provide a user interface. You get time like
  777. any other application.
  778.  
  779. --Brian Bechtel     blob@apple.com     "My opinion, not Apple's"
  780.  
  781. ---------------------------
  782.  
  783. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  784. Subject: Self-disposing notification crashes
  785. Date: 16 Sep 94 16:35:09 +1200
  786. Organization: University of Waikato, Hamilton, New Zealand
  787.  
  788. I'm working on this MPW tool that sends a PostScript stream to a printer via
  789. PAP, and displays whatever the printer sends back. It loads the PDEF 10 code
  790. from the LaserWriter driver (I know, I know, but this is for in-house use,
  791. and I have ways of keeping it working under QuickDraw GX ;-)). However,
  792. I didn't like the PAPStatus call that that library provides, as it's
  793. synchronous, and tends to hang for several seconds if the printer goes away.
  794.  
  795. So I tried implementing my own version of PAPStatus. My version allocates
  796. a temporary block in the heap, which is used to contain the context for the
  797. call, including pointers to the user's data areas. Once the query starts,
  798. everything runs at interrupt time as a sequence of chained completion routines
  799. from then on, except of course for the last bit of code that gets rid of the
  800. temporary block. This code runs as a notification routine, so that it's safe
  801. for it to make Memory Manager calls.
  802.  
  803. The notification code is actually copied into the temporary block, and executes
  804. out of there. I did this as part of a strategy for dealing cleanly with aborting
  805. execution of the tool, though admittedly my handling of this is not complete
  806. as yet.
  807.  
  808. Anyway, this notification routine is very small, and is written in assembler.
  809. Here it is in its entirety:
  810.  
  811.     move.l    4(sp), a0
  812.     _NMRemove
  813.     move.l    NMRec.nmRefCon(a0), a0
  814.     _DisposePtr
  815.     move.l    (sp)+, (sp)
  816.     rts
  817.  
  818. Note that the DisposePtr call is disposing of the block containing the code
  819. (and the notification record) itself! However, I have stepped through this
  820. code with MacsBug, and watched it successfully return from DisposePtr and
  821. execute those last two instructions just fine.
  822.  
  823. Basically, the problem is, my tool tends to crash, but only the second time
  824. it runs. The first time is always fine: I can send a large multi-page print
  825. job to the printer (with lots of status queries throughout), or I can send
  826. a small one-line query, and it will always work. However, the second time I
  827. try invoking my tool, it will crash.
  828.  
  829. I finally narrowed it down to one thing: the DisposePtr call in the
  830. notification routine, above. If I no-op out the dispose call (causing a
  831. resultant accumulation of allocated memory blocks in MPW's heap), I can run the
  832. tool multiple times just fine.
  833.  
  834. Anybody got any ideas as to why this can't work?
  835.  
  836. Thanks for any help.
  837.  
  838. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  839. Info & Tech Services Division              fax: +64-7-838-4066
  840. University of Waikato            electric mail: ldo@waikato.ac.nz
  841. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  842.  
  843. +++++++++++++++++++++++++++
  844.  
  845. >From pottier@fregate.ens.fr (Francois Pottier)
  846. Date: 16 Sep 1994 11:28:28 GMT
  847. Organization: Ecole Normale Superieure, PARIS, France
  848.  
  849. In article <1994Sep16.163509.33240@waikato.ac.nz>,
  850. Lawrence D'Oliveiro, Waikato University <ldo@waikato.ac.nz> wrote:
  851. >
  852. >Anyway, this notification routine is very small, and is written in assembler.
  853. >Here it is in its entirety:
  854. >
  855. >    move.l    4(sp), a0
  856. >    _NMRemove
  857. >    move.l    NMRec.nmRefCon(a0), a0
  858. >    _DisposePtr
  859. >    move.l    (sp)+, (sp)
  860. >    rts
  861. >
  862. >Note that the DisposePtr call is disposing of the block containing the code
  863.  
  864. I'm interested in this problem too. My notification routine looks exactly
  865. the same way. It works perfectly, but I'm concerned that it might break in
  866. the future.
  867.  
  868. Apple has warned against this sort of thing; once the block is freed, you
  869. can't make any assumptions about its contents (so you can't execute code in
  870. it). This makes sense; in a preemptive multitasking system, the block could
  871. very well by allocated by another process before you have time to rts out of
  872. it.
  873.  
  874. However, I don't see any other way of disposing properly of the Notification
  875. Record. If you want your notification to appear after your normal code is
  876. dead (INITs need to do that), then you must copy the response proc into a
  877. standalone block in the System heap. And if you want to clean up properly,
  878. you should release this block after it's been used. So there appears to be
  879. no way to do the Right Thing here.
  880.  
  881. I'd be interested in comments...
  882.  
  883.  
  884.  
  885.  
  886. -- 
  887. Francois Pottier                                            pottier@dmi.ens.fr
  888. - ----------------------------------------------------------------------------
  889. Check my WWW page at http://acacia.ens.fr:8080/home/pottier/index.html ...
  890.  
  891. +++++++++++++++++++++++++++
  892.  
  893. >From Jaeger@fquest.com (Brian Stern)
  894. Date: 16 Sep 1994 15:48:28 GMT
  895. Organization: The University of Texas at Austin, Austin, Texas
  896.  
  897. In article <35bvgs$h87@nef.ens.fr>, pottier@fregate.ens.fr (Francois
  898. Pottier) wrote:
  899.  
  900.  
  901. < However, I don't see any other way of disposing properly of the Notification
  902. < Record. If you want your notification to appear after your normal code is
  903. < dead (INITs need to do that), then you must copy the response proc into a
  904. < standalone block in the System heap. And if you want to clean up properly,
  905. < you should release this block after it's been used. So there appears to be
  906. < no way to do the Right Thing here.
  907. < I'd be interested in comments...
  908. < -- 
  909. < Francois Pottier                                            pottier@dmi.ens.fr
  910. < ------------------------------------------------------------------------------
  911. < Check my WWW page at http://acacia.ens.fr:8080/home/pottier/index.html ...
  912.  
  913. If you check out Dair Grant's Init Shell package, at an ftp site near you,
  914. you'll find some code that gets around this problem.  It works by poking
  915. several instructions into ToolScratch, including the disposePtr, and then
  916. jumping to those instructions.  I believe this is based on some code that
  917. was in the old usenet mac programmers guide.
  918.  
  919. Cheers,
  920.  
  921. -- 
  922. Brian  Stern  :-{)}
  923. Jaeger@fquest.com
  924.  
  925. +++++++++++++++++++++++++++
  926.  
  927. >From resnick@uiuc.edu (Pete Resnick)
  928. Date: Fri, 16 Sep 1994 15:00:26 -0500
  929. Organization: University of Illinois at Urbana-Champaign
  930.  
  931. In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  932. (Lawrence D'Oliveiro, Waikato University) wrote:
  933.  
  934. > Anyway, this notification routine is very small, and is written in assembler.
  935. > Here it is in its entirety:
  936. >         move.l  4(sp), a0
  937. >         _NMRemove
  938. >         move.l  NMRec.nmRefCon(a0), a0
  939. >         _DisposePtr
  940. >         move.l  (sp)+, (sp)
  941. >         rts
  942. > Note that the DisposePtr call is disposing of the block containing the code
  943. > (and the notification record) itself! However, I have stepped through this
  944. > code with MacsBug, and watched it successfully return from DisposePtr and
  945. > execute those last two instructions just fine.
  946.  
  947. Yow!! This would be bad since you can't depend on when that memory is
  948. going to be overwritten, and for you, it's happening in the call to
  949. _DisposePtr. There are two ways around this:
  950.  
  951. On anything better than a 68010 (which is all Macs except for the classic
  952. one) there is a wonderful little instruction: RTD. That instruction
  953. returns, but also simultaneously deallocates space on the stack. So, what
  954. I do is call _NMRemove (and whatever other cleanup I want to do) and then
  955. move the _DisposePtr and an RTD instruction to the stack:
  956.  
  957.         move.l  4(sp),a0                ; Move the NMRec
  958.         _NMRemove                       ; Remove it
  959.         move.l  NMRec.nmRefCon(a0),a1   ; Address of code+NMRec into A1
  960.         movea.l (sp)+,a0                ; Return address into A0
  961.         move.l  #$4E740006,-(sp)        ; RTD #$0006
  962.         move.w  #$a01f,-(sp)            ; _DisposePtr
  963.         move.l  a0,-(sp)                ; Return address back onto stack
  964.         pea     4(sp)                   ; Address of _DisposePtr on stack
  965.         moveq   #$1,d0
  966.         _HWPriv                         ; Flush the cache
  967.         movea.l a1,a0                   ; Address to dispose
  968.         rts                             ; Return to _DisposePtr on stack
  969.  
  970. So the stack (before the final RTS) looks like:
  971.  
  972.         +0000   <sp + 8>
  973.         +0004   <old return address>
  974.         +0008   _DisposePtr
  975.         +000A   RTD #$0006
  976.         .....Rest of stack
  977.  
  978. So when that last RTS executes, it rips the address of sp+8 off of the
  979. stack and jumps to it. The _DisposePtr disposes what's in A0 (the code and
  980. the NMRec), then the RTD takes the old return address off the stack, moves
  981. the stack pointer 6 bytes (past the _DisposePtr and the RTD #$0006), and
  982. jumps to the return address. Frightening, eh?
  983.  
  984. On the old 68000, you don't have the RTD instruction (nor an instruction
  985. cache), but life is generally a good deal simpler: There is a low memory
  986. global called "ToolScratch", which is an 8-byte scratch area. It stays
  987. constant across the call to _DisposePtr, so what you can do instead is:
  988.  
  989.         move.l  4(sp),a1                ; Move the NMRec
  990.         move.l  (sp)+,(sp)              ; Move the return address into place
  991.         _NMRemove                       ; Remove it
  992.         move.l  NMRec.nmRefCon(a1),a0   ; Address of code+NMRec into A0
  993.         movea.w #ToolScratch,a1         ; Address of the LM global
  994.         move.l  a1,-(sp)                ; Put the address onto the stack
  995.         move.l  #$a01f4E75,(a1)         ; _DisposePtr / RTS
  996.         rts
  997.  
  998. So now the stack looks like:
  999.  
  1000.         +0000   <address of ToolScratch>
  1001.         +0004   <old return address>
  1002.         .....Rest of stack
  1003.  
  1004. And ToolScratch has in it:
  1005.  
  1006.         _DisposePtr
  1007.         RTS
  1008.  
  1009. This has worked perfectly for me. Executing code on the stack is pretty
  1010. wierd, but it works just great.
  1011.  
  1012. pr
  1013. -- 
  1014. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  1015. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  1016. System manager - Cognitive Science Group, Beckman Institute, UIUC
  1017. Internet: resnick@uiuc.edu
  1018.  
  1019. +++++++++++++++++++++++++++
  1020.  
  1021. >From jberry@teleport.com (James D. Berry)
  1022. Date: Fri, 16 Sep 1994 13:39:16 -0700
  1023. Organization: Consultant
  1024.  
  1025. In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  1026. (Lawrence D'Oliveiro, Waikato University) wrote:
  1027.  
  1028. > Anyway, this notification routine is very small, and is written in assembler.
  1029. > Here it is in its entirety:
  1030. >         move.l  4(sp), a0
  1031. >         _NMRemove
  1032. >         move.l  NMRec.nmRefCon(a0), a0
  1033. >         _DisposePtr
  1034. >         move.l  (sp)+, (sp)
  1035. >         rts
  1036. > Note that the DisposePtr call is disposing of the block containing the code
  1037. > (and the notification record) itself! However, I have stepped through this
  1038. > code with MacsBug, and watched it successfully return from DisposePtr and
  1039. > execute those last two instructions just fine.
  1040.  
  1041. I can't see the rest of your code, but it strikes me that if for some
  1042. reason the NMRemove call is being passed an incorrect value, then you'd be
  1043. leaving a bogus link in the NMQueue (because you've deleted the code it's
  1044. pointing to) which would cause a crash on the next invokation.
  1045.  
  1046. I'm a purest at heart, and also don't like the fact that you're executing
  1047. two instructions out of a block that's been disposed. The Modern Memory
  1048. Manager, in fact, has a debug mode that'll trash blocks as they're
  1049. disposed, which should break your code.
  1050.  
  1051. I use the following code to (cleanly?) cleanup following a notification.
  1052. Note that it assumes the NMRec and supporting code are all allocated into
  1053. a single heap block. It hasn't yet (!!) managed to break the 68K emulator,
  1054. though it seems a good target to :-()  Now if Apple would just give us a
  1055. few NM flags that specify a block to be deleted following notification!
  1056.  
  1057. ;------------------------------------------------------------
  1058. ;  pascal void NotifyProc(NMRecPtr pRec)
  1059. ;
  1060. ;  The notify proc. Its sole purpose in life is to
  1061. ;  clean-up following the notification manager.
  1062. ;------------------------------------------------------------
  1063. NotifyProc        proc
  1064.                machine  mc68020
  1065.                entry NotifyProcLen
  1066.  
  1067.                subq     #2,sp                ; Extra space 8 bytes --> 10 bytes
  1068.                move.l   2(sp),-(sp)          ; Move Return address
  1069.                move.l   10(sp),-(sp)         ; Move NMRecPtr
  1070.                
  1071.                lea      @StackCodeEnd,a1     ; Move our _DisposePtr code
  1072. onto stack
  1073.                lea      14(sp),a0            ; so that we can suicide cleanly!
  1074.                move.l   -(a1),-(a0)          ; rtd #x
  1075.                move.w   -(a1),-(a0)          ; _DisposePtr
  1076.                moveq    #6,d0                ; Length of the code
  1077.                move.l   d0,a1                ; into a1
  1078.                
  1079.                _FlushCodeCacheRange          ; Flush the caches where we
  1080. wrote code
  1081.                
  1082.                move.l   a0,a1                ; Pointer to our cleanup code
  1083. on stack
  1084.                move.l   (sp)+,a0             ; Get NMRecPtr
  1085.                
  1086.                _NMRemove                     ; Unqueue the NMRec
  1087.                
  1088.                jmp      (a1)                 ; Call cleanup code to
  1089. dispose the block we're
  1090.                                              ; currently executing out of
  1091.                                           
  1092.                ;  This code will be moved onto the stack
  1093.                ;  before it is executed, so that we don't
  1094.                ;  execute code out of a deallocated block
  1095.                
  1096.                _DisposePtr                   ; Dispose the
  1097. NMRec/code/string block
  1098.                rtd      #6                   ; Return to caller,
  1099. deallocating this code!
  1100. @StackCodeEnd
  1101.  
  1102. NotifyProcLen  dc.l  *-NotifyProc            ; Length of our notification proc
  1103.  
  1104.                endp
  1105.  
  1106. -- 
  1107. James Berry
  1108. jberry@teleport.com
  1109.  
  1110. +++++++++++++++++++++++++++
  1111.  
  1112. >From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
  1113. Date: Sat, 17 Sep 1994 14:50:34 +1200 (NZST)
  1114. Organization: (none)
  1115.  
  1116. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  1117. > I'm working on this MPW tool that sends a PostScript stream to a printer via
  1118. > PAP, and displays whatever the printer sends back.
  1119.  
  1120. Heh.  I turned your downloader XCMDs into an MPW Tool only about -- what? --
  1121. seven years ago.
  1122.  
  1123.  
  1124. > It loads the PDEF 10 code
  1125. > from the LaserWriter driver (I know, I know, but this is for in-house use
  1126. > and I have ways of keeping it working under QuickDraw GX ;-)).
  1127.  
  1128. Hmm.  Looks as if I'm going to need an update :-(
  1129.  
  1130.  
  1131. > I finally narrowed it down to one thing: the DisposePtr call in the
  1132. > notification routine, above. If I no-op out the dispose call (causing a
  1133. > resultant accumulation of allocated memory blocks in MPW's heap), I can run the
  1134. > tool multiple times just fine.
  1135. > Anybody got any ideas as to why this can't work?
  1136.  
  1137. It's not going to like the Modern Memory Manager, which stores some info
  1138. inside your data block as soon as you dispose it.
  1139.  
  1140. OTOH, if the last two instructions are surviving then it's hard to see what's
  1141. going wrong.  You *are* allocating a new block and a new copy of the code
  1142. each time you use it, right?
  1143.  
  1144. Might you not be better to allocate a small block the first time you run
  1145. and just leave it alive?  And use Gestalt or something to find it each time?
  1146.  
  1147. -- Bruce
  1148.  
  1149. +++++++++++++++++++++++++++
  1150.  
  1151. >From ludis@netcom.com (Ludis Langens)
  1152. Date: Sat, 17 Sep 1994 23:28:18 GMT
  1153. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  1154.  
  1155. In article <35bvgs$h87@nef.ens.fr> pottier@fregate.ens.fr (Francois Pottier) writes:
  1156. >In article <1994Sep16.163509.33240@waikato.ac.nz>,
  1157. >Lawrence D'Oliveiro, Waikato University <ldo@waikato.ac.nz> wrote:
  1158. >>
  1159. >>Anyway, this notification routine is very small, and is written in assembler.
  1160. >>Here it is in its entirety:
  1161. >>
  1162. >>    move.l    4(sp), a0
  1163. >>    _NMRemove
  1164. >>    move.l    NMRec.nmRefCon(a0), a0
  1165. >>    _DisposePtr
  1166. >>    move.l    (sp)+, (sp)
  1167. >>    rts
  1168. >>
  1169. >>Note that the DisposePtr call is disposing of the block containing the code
  1170. >
  1171. >I'm interested in this problem too. My notification routine looks exactly
  1172. >the same way. It works perfectly, but I'm concerned that it might break in
  1173. >the future.
  1174. >
  1175. >Apple has warned against this sort of thing; once the block is freed, you
  1176. >can't make any assumptions about its contents (so you can't execute code in
  1177. >it). This makes sense; in a preemptive multitasking system, the block could
  1178. >very well by allocated by another process before you have time to rts out of
  1179. >it.
  1180. >
  1181. >However, I don't see any other way of disposing properly of the Notification
  1182. >Record. If you want your notification to appear after your normal code is
  1183. >dead (INITs need to do that), then you must copy the response proc into a
  1184. >standalone block in the System heap. And if you want to clean up properly,
  1185. >you should release this block after it's been used. So there appears to be
  1186. >no way to do the Right Thing here.
  1187.  
  1188. To dispose the memory block out of which you are executing, try this:
  1189.  
  1190. BlockStart EQU *
  1191.  
  1192.         ...
  1193.         MOVEQ   #$1F,D0           ;Trap number of DisposPtr
  1194.         _GetTrapAddress OS
  1195.         MOVE.L  A0,A1
  1196.         LEA     BlockStart(PC),A0
  1197.         JMP     (A1)
  1198.  
  1199. Use this code as the very last thing you execute.  Make sure you have
  1200. removed any parameters from the stack (so that an RTS can return to
  1201. your caller.)  The JMP (A1) goes to the memory manager directly,
  1202. bypassing the trap dispatcher.  This means that registers D0-D2/A0-A1
  1203. may be changed.  Once DisposPtr has freed the block, it will return
  1204. (directly) to your caller.  When you link your code fragment, make sure
  1205. that BlockStart is at offset 0 in the memory block.  This same trick
  1206. can be also be used with handles by adding a RecoverHandle (and getting
  1207. the address of DisposHandle.)
  1208.  
  1209. Ludis Langens
  1210. ludis@netcom.com
  1211.  
  1212. +++++++++++++++++++++++++++
  1213.  
  1214. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  1215. Date: 19 Sep 94 14:24:01 +1200
  1216. Organization: University of Waikato, Hamilton, New Zealand
  1217.  
  1218. In article <jberry-1609941339160001@ip-ce.teleport.com>, jberry@teleport.com (James D. Berry) writes:
  1219. > In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  1220. > (Lawrence D'Oliveiro, Waikato University) wrote:
  1221. >
  1222. >> Anyway, this notification routine is very small, and is written in assembler.
  1223. >> Here it is in its entirety:
  1224. >>
  1225. >>         move.l  4(sp), a0
  1226. >>         _NMRemove
  1227. >>         move.l  NMRec.nmRefCon(a0), a0
  1228. >>         _DisposePtr
  1229. >>         move.l  (sp)+, (sp)
  1230. >>         rts
  1231. >>
  1232. >> Note that the DisposePtr call is disposing of the block containing the code
  1233. >> (and the notification record) itself! However, I have stepped through this
  1234. >> code with MacsBug, and watched it successfully return from DisposePtr and
  1235. >> execute those last two instructions just fine.
  1236. >
  1237. > I can't see the rest of your code, but it strikes me that if for some
  1238. > reason the NMRemove call is being passed an incorrect value, then you'd be
  1239. > leaving a bogus link in the NMQueue (because you've deleted the code it's
  1240. > pointing to) which would cause a crash on the next invokation.
  1241.  
  1242. The NMRec address must be correct, because its nmRefCon contains the pointer
  1243. to the entire block, which is indeed being correctly disposed. (Like I said,
  1244. I checked this with MacsBug.)
  1245.  
  1246. > I'm a purest at heart, and also don't like the fact that you're executing
  1247. > two instructions out of a block that's been disposed. The Modern Memory
  1248. > Manager, in fact, has a debug mode that'll trash blocks as they're
  1249. > disposed, which should break your code.
  1250.  
  1251. That must be the only memory manager in the world that does that...
  1252.  
  1253. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  1254. Info & Tech Services Division              fax: +64-7-838-4066
  1255. University of Waikato            electric mail: ldo@waikato.ac.nz
  1256. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  1257. "Icons are the droppings located at the top and sides of the Windows display."
  1258.                        -- reported in PC Magazine
  1259.  
  1260. +++++++++++++++++++++++++++
  1261.  
  1262. >From jan3@po.cwru.edu (James A. Nauer)
  1263. Date: Mon, 19 Sep 1994 17:18:49 -0400
  1264. Organization: Case Western Reserve University
  1265.  
  1266. In article <1994Sep19.142402.33297@waikato.ac.nz>, ldo@waikato.ac.nz
  1267. (Lawrence D'Oliveiro, Waikato University) wrote:
  1268.  
  1269. > In article <jberry-1609941339160001@ip-ce.teleport.com>,
  1270. jberry@teleport.com (James D. Berry) writes:
  1271. > >
  1272. > > I'm a purest at heart, and also don't like the fact that you're executing
  1273. > > two instructions out of a block that's been disposed. The Modern Memory
  1274. > > Manager, in fact, has a debug mode that'll trash blocks as they're
  1275. > > disposed, which should break your code.
  1276. > That must be the only memory manager in the world that does that...
  1277.  
  1278. Not true.  I have an anti-virus TSR on my PC which, among other things,
  1279. patches the (feeble) DOS memory management routines to zero out all freed
  1280. blocks before returning.  Naturally, I also have a couple of programs that
  1281. fail because they think they can get away with using a few bytes of data
  1282. in a block _after_ freeing it :-(.
  1283. -- 
  1284. James A. Nauer             | "I shall not yield one whit of maturity,
  1285. Library Information        | not grace, not respectibility, to the 
  1286. Technologies               | passing of time. I declare that I shall
  1287. Case Western Reserve Univ. | forever be, if not a child, certainly
  1288. (216) 368-MACS  (368-6227) | childish"  --Kennet Shardik
  1289.  
  1290. +++++++++++++++++++++++++++
  1291.  
  1292. >From h+@nada.kth.se (Jon W{tte)
  1293. Date: Tue, 20 Sep 1994 10:36:19 +0200
  1294. Organization: Royal Institute of Something or other
  1295.  
  1296. In article <1994Sep19.142402.33297@waikato.ac.nz>,
  1297. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) wrote:
  1298.  
  1299. >> two instructions out of a block that's been disposed. The Modern Memory
  1300. >> Manager, in fact, has a debug mode that'll trash blocks as they're
  1301. >> disposed, which should break your code.
  1302. >
  1303. >That must be the only memory manager in the world that does that...
  1304.  
  1305. Not at all; several malloc() implementations IMMEDIATELY writes 
  1306. data into the block being disposed, like a pointer in a linked 
  1307. list of free blocks, or something like that.
  1308.  
  1309. Using a block after disposing it is BAD BAD BAD. The 
  1310. Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1311. depends on the fact that DisposePtr uses register calling 
  1312. conventions.
  1313.  
  1314. Cheers,
  1315.  
  1316.                 / h+
  1317.  
  1318.  
  1319. --
  1320.   Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  1321.  V}ga v{gra nonkonformism!
  1322.  
  1323.  
  1324. +++++++++++++++++++++++++++
  1325.  
  1326. >From fixer@faxcsl.dcrt.nih.gov (Chris Biscottimeister Tate)
  1327. Date: Tue, 20 Sep 1994 18:44:17 GMT
  1328. Organization: DCRT, NIH, Bethesda, MD
  1329.  
  1330. In article <1994Sep19.142402.33297@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  1331. >In article <jberry-1609941339160001@ip-ce.teleport.com>, jberry@teleport.com (James D. Berry) writes:
  1332. >>
  1333. >> I'm a purist at heart, and also don't like the fact that you're executing
  1334. >> two instructions out of a block that's been disposed. The Modern Memory
  1335. >> Manager, in fact, has a debug mode that'll trash blocks as they're
  1336. >> disposed, which should break your code.
  1337. >
  1338. >That must be the only memory manager in the world that does that...
  1339.  
  1340. I seem to recall running into some odd situations in which the system was
  1341. writing into unallocated heap memory for some reason.  Quickdraw, maybe?
  1342.  
  1343. (I would think that executing out of a just-deallocated block is pretty
  1344. much a recipe for disaster - certainly in a preemptive-multitasking world
  1345. you're doomed if you do it, barring some IMHO unwarranted privileges being
  1346. granted to your code...)
  1347.  
  1348. - ------------------------------------------------------------------
  1349. Christopher Tate           | "Apple Guide makes Windows' help engine
  1350. MSD, Inc.                  |  look like a quadruple amputee."
  1351. fixer@faxcsl.dcrt.nih.gov  |      -- Pete Gontier (gurgle@dnai.com)
  1352.  
  1353. +++++++++++++++++++++++++++
  1354.  
  1355. >From rang@winternet.com (Anton Rang)
  1356. Date: 21 Sep 1994 01:06:37 GMT
  1357. Organization: Trillium Research, Inc.
  1358.  
  1359. In article <9668AAA46BA3.6ED60@klkmac018.nada.kth.se> h+@nada.kth.se (Jon W{tte) writes:
  1360. >Using a block after disposing it is BAD BAD BAD. The 
  1361. >Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1362. >depends on the fact that DisposePtr uses register calling 
  1363. >conventions.
  1364.  
  1365.   Actually, you're fine with Pascal calling conventions, too, since
  1366. the callee is responsible for cleaning up the stack.  It's only if you
  1367. are trying to use C calling conventions that you'll have problems with
  1368. exiting via a call to another routine.
  1369. --
  1370. Anton Rang (rang@winternet.com)
  1371.  
  1372. +++++++++++++++++++++++++++
  1373.  
  1374. >From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
  1375. Date: Wed, 21 Sep 1994 14:48:10 +1200 (NZST)
  1376. Organization: (none)
  1377.  
  1378. resnick@uiuc.edu (Pete Resnick) writes:
  1379. > On anything better than a 68010 (which is all Macs except for the classic
  1380. > one) there is a wonderful little instruction: RTD. That instruction
  1381. > returns, but also simultaneously deallocates space on the stack. So, what
  1382. > I do is call _NMRemove (and whatever other cleanup I want to do) and then
  1383. > move the _DisposePtr and an RTD instruction to the stack:
  1384.  
  1385. Arrrrggghhh!!!
  1386.  
  1387. There are a *lot* of PowerBook 100's out there, filled to the gills with
  1388. RAM, and with a long useful life ahead of them still -- I expect to be
  1389. using mine for years yet, even though I've got a PowerMac as my main
  1390. machine.
  1391.  
  1392. In case you didn't realise, the PB100 uses an original 68000 chip.
  1393.  
  1394. -- Bruce
  1395.  
  1396. +++++++++++++++++++++++++++
  1397.  
  1398. >From ludis@netcom.com (Ludis Langens)
  1399. Date: Fri, 23 Sep 1994 21:25:04 GMT
  1400. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  1401.  
  1402. In article <9668AAA46BA3.6ED60@klkmac018.nada.kth.se> h+@nada.kth.se (Jon W{tte) writes:
  1403. >Using a block after disposing it is BAD BAD BAD. The 
  1404. >Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1405. >depends on the fact that DisposePtr uses register calling 
  1406. >conventions.
  1407.  
  1408. The Cleanup/GetTrapAddress/Jump solution does not depend upon its target
  1409. trap using register calling conventions.  A Pascal style trap can also be
  1410. called this way - just rearrange the stack appropriately.  What it does
  1411. depend upon is the register preservation and stack usage of the trap you
  1412. are chaining to.  It could not be used to chain to a C style function
  1413. or to anything that trashes registers which your function must preserve.
  1414.  
  1415. If you need to chain to a toolbox trap, the GetTrapAddress step can be
  1416. omitted by using a trap with the Auto-pop bit set.  This is a very
  1417. 'official' way of jumping to a trap.  (Years ago I used this trick
  1418. to create code segments that self UnloadSeg-ed themselves upon returning
  1419. to their caller.)
  1420.  
  1421. Ludis Langens
  1422. ludis@netcom.com
  1423.  
  1424. ---------------------------
  1425.  
  1426. >From fairgate@vespucci.iquest.com (Fairgate Technologies)
  1427. Subject: [CWWWW] PowerPlant Tour document available
  1428. Date: 23 Sep 1994 15:53:13 -0500
  1429. Organization: interQuest -- Fuel for the Mind
  1430.  
  1431. Thanks to Marc Paquette of Metrowerks, there's now a PowerPlant Tour
  1432. document on CWWWW, along with some other supporting PowerPlant
  1433. material.
  1434.  
  1435. For those of you who know what CWWWW is, these new goodies are
  1436. available on the PowerPlant Central
  1437. (http://www.iquest.com/~fairgate/cw/pplant.html) page.
  1438.  
  1439. If you haven't visited CWWWW yet, come on down! CWWWW is the official
  1440. CodeWarrior World-Wide Web site. IMNSHO there's quite a bit of useful
  1441. information there, especially for the relatively undocumented
  1442. PowerPlant class library. 
  1443.  
  1444. Point your WWW browser at http://www.iquest.com/~fairgate.
  1445.  
  1446. Cheers,
  1447. -Paul
  1448.  
  1449. [ If you don't get a reply from me with 48hrs, please resend your message.
  1450.   The Mail Gods are displeased; incoming mail is sometimes silently dropped. ]
  1451.  
  1452.  
  1453. -- 
  1454.  Paul Robichaux       Fairgate Technologies         paul@fairgate.com
  1455.       Fairgate Technologies does custom Mac development.
  1456.   Visit the CodeWarrior WWW page at http://www.iquest.com/~fairgate.
  1457.  
  1458. ---------------------------
  1459.  
  1460. End of C.S.M.P. Digest
  1461. **********************
  1462.  
  1463.  
  1464.